import java.util.*;
import java.io.*;

/**
 * PROGRAMACIO DE LES EXCEPCIONS */
/** Excepcio que s'utilitzara en cas de Que en el Lloc Inicial no hi haguin unitats que
 * es puguin moure*/
class NoUnitatsException extends Exception
{
	NoUnitatsException()
    {
        super();
    }
	NoUnitatsException(String s)
    {
        super(s);
    }
}
/** Excepcio que s'utilitzara en el cas de que en el lloc Final hi hagi presencia militar*/
class NoPresenciaMilitarException extends Exception
{
	NoPresenciaMilitarException()
    {
        super();
    }
	NoPresenciaMilitarException(String s)
    {
        super(s);
    }
}

/** Excepcio que s'utilitzara en el cas de que no es trobi l'etnia el lloc final o el lloc inicial*/
class NoElementTrobatException extends Exception
{
	NoElementTrobatException()
    {
        super();
    }
	NoElementTrobatException(String s)
    {
        super(s);
    }
}

/** Excepcio que s'utilitzara en el cas que els civils no es puguin moure del enclavament Inicial al final*/
class CivilsNoPodenArribarException extends Exception
{
	CivilsNoPodenArribarException()
    {
        super();
    }
	CivilsNoPodenArribarException(String s)
    {
        super(s);
    }
}

/**Excepcio que s'utilitzara en el cas que en el enclavament inicial no hi hagin civils*/
class NoCivilsException extends Exception
{
	NoCivilsException()
    {
        super();
    }
	NoCivilsException(String s)
    {
        super(s);
    }
}
	
/** Excepcio que s'utilitzara en el el cas que en el enclavament final hi hagin civils de l'etnia que els vol moure*/
class PresenciaCivilException extends Exception
{
	PresenciaCivilException()
	{
		super();
	}
	PresenciaCivilException(String s)
	{
		super(s);
	}
}	

/** Excepcio que s'utilitzara en el cas de que en el enclavament final hi hagi presencia militar*/
class PresenciaMilitarException extends Exception
{
	PresenciaMilitarException()
	{
		super();
	}
	PresenciaMilitarException(String s)
	{
		super(s);
	}
}

/**Excepcio que s'utilitzara en el cas de que la etnia no existeixi*/
class EtniaException extends Exception
{
	EtniaException()
    {
        super();
    }
	EtniaException(String s)
    {
        super(s);
    }
}

class OcupantException extends Exception
{
	OcupantException()
    {
        super();
    }
	OcupantException(String s)
    {
        super(s);
    }
}


/** @brief Clase que dura la mecanica del joc, es dir el que executara els canvi sobre map.*/
public class joc{
	
	private Mapa map; /** @var Mapa al qual s'executaran les comandes*/
	private TreeMap<String,Etnia> etnies;/** @var Conjunt de totes les etnies*/
	int nEtnies;/** @var  numero de etnies*/
	
	/**
	 @pre:
	 @post: Constructor per defecte*/
	public joc(){
		map = new Mapa();
		etnies = new TreeMap();
		nEtnies = 0 ;
	}
	
	/**
	 @pre:
	 @post: Cosntructor amb parametres*/
	public joc(int nEtnies)
	{
		map = new Mapa();
		etnies = new TreeMap();
		nEtnies = 0 ;
	}
	/**
	 @pre:
	 @post: afegeix l'etnia inEtnia al mapa*/
	public void afegeirEtnia(Etnia inEtnia)
	{
		etnies.put(inEtnia.nom(),inEtnia);
		nEtnies++;
	}
	
	  /**@pre:- -
	  @post: retorna el map del joc */
	public Mapa mapaJoc()
	{return map;}
	
	
	  /**@pre:- -
	  @post: retorna el map que conté totes les etnies del joc */
	public TreeMap<String,Etnia> ObtEtnies(){
		return etnies;
	}
	/**
	 @pre: Map no buit
	 @post: retorna la unitat amb la potencia m�s elevada de unitats */
	public Unitat triarUnitatMesPotent(Map<String,Unitat> unitats)
	{
		double maxPotencia=-1;
		Unitat unitatMesPotent= null;
		Unitat uIteradora = null;
		Iterator iterator = unitats.entrySet().iterator();
		while (iterator.hasNext())
		{
			Map.Entry<String,Unitat> mapEntry = (Map.Entry) iterator.next();
			uIteradora =  mapEntry.getValue();
			if (uIteradora.potencia()> maxPotencia)
			{
				unitatMesPotent =  mapEntry.getValue();
				maxPotencia = unitatMesPotent.potencia();
			}
		}
		return unitatMesPotent;
	}
	/**
	 @pre: Map no buit
	 @post: retorna la unitat amb la potencia m�s elevada de unitats que pugi anar de atacant a defensor */
	public Unitat triarUnitatMesPotent(Enclavament atacant,Enclavament defensor,Map<String,Unitat> grupAtacant)
	{

		double maxPotencia = -1;
		Unitat unitatMesPotent=null;
		Unitat uIteradora;
		Iterator iterator=grupAtacant.entrySet().iterator();
		while (iterator.hasNext())
		{
			Map.Entry<String,Unitat> mapEntry = (Map.Entry) iterator.next();
			if (mapEntry.getValue().potencia()> maxPotencia && mapEntry.getValue().esPosibleMoure(atacant,defensor))
			{
				unitatMesPotent =  mapEntry.getValue();
				maxPotencia = unitatMesPotent.potencia();
			}
		}
		return unitatMesPotent;
	}
	
	  /**@pre:- -
	  @post: retorna l'unitat mes potent de l'atacant que pugui arribar a l'enclavament defensor */
	public Unitat triarUnitatMesPotent(Enclavament atacant,Enclavament defensor)
	{
		double maximPotencia = -1;
		Unitat unitatMesPotent= null;
                Iterator iterator = atacant.Obtunitats().entrySet().iterator();
		while(iterator.hasNext())
		{
                    Map.Entry<String,Unitat> mapEntry = (Map.Entry) iterator.next();
			if((mapEntry.getValue().potencia() > maximPotencia)&& mapEntry.getValue().esPosibleMoure(atacant,defensor))
			{
				unitatMesPotent = mapEntry.getValue();
				maximPotencia = unitatMesPotent.potencia();
			}
		}
		return unitatMesPotent;
	}
	/**
	 @pre: Map no buit
	 @post: retorna la unitat amb la potencia menys elevada de unitats que pot anar de atacant a defensor */
	
	public Unitat triarUnitatMenysPotent(Enclavament atacant,Enclavament defensor)
	{
		double minimPotencia = -1;
		Unitat unitatMenysPotent= null;
                Iterator iterator = atacant.Obtunitats().entrySet().iterator();
		while(iterator.hasNext())
		{
                    Map.Entry<String,Unitat> mapEntry = (Map.Entry) iterator.next();
			if((mapEntry.getValue().potencia() < minimPotencia || minimPotencia ==-1)&& mapEntry.getValue().esPosibleMoure(atacant,defensor))
			{
				unitatMenysPotent = mapEntry.getValue();
				minimPotencia = unitatMenysPotent.potencia();
			}
		}
		return unitatMenysPotent;
	}
	/**
	 @pre: Map no buit
	 @post: retorna la unitat amb la potencia menys elevada de unitats */
	
	public Unitat triarUnitatMenysPotent(Map<String,Unitat> unitats)
	{
		double minimPotencia =-1;
		Unitat unitatMenysPotent = null;
                Iterator iterator = unitats.entrySet().iterator();
		while(iterator.hasNext())
		{
                    Map.Entry<String,Unitat> mapEntry = (Map.Entry)iterator.next();
			if (mapEntry.getValue().potencia()< minimPotencia || minimPotencia==-1)
			{
				unitatMenysPotent = mapEntry.getValue();
				minimPotencia = unitatMenysPotent.potencia();
			}
		}
		return unitatMenysPotent;
	}
	/**
	 @Pre: 
	 @Post: retorna una llista amb les unitats que realitzaran el atac de inicial a final segons l'estrategia
	 sempre ha de quedar una unitat en el enclavament Atacant*/
	public Map<String,Unitat> unitatsPerAtacar(Enclavament atacant,Enclavament defensor, String estrategia)
	{
		Map<String,Unitat> grupAtacant = new TreeMap();
		Unitat uAtacant = null;
		if (atacant.ocupa().estrategia().equals("conservador"))
		{
			if (atacant.Obtunitats().size()>1)
			{
				uAtacant = triarUnitatMenysPotent(atacant,defensor);
				if (uAtacant != null)
				{
					grupAtacant.put(uAtacant.nom(),uAtacant);
					atacant.treureUnitat(atacant.obtNom());
				}
			}
		}
		else
		{
			//TRACTAMENT DEL PRIMERA UNITAT
			if (atacant.Obtunitats().size()>1)
			{
				uAtacant = triarUnitatMesPotent(atacant,defensor);
			}
			if (uAtacant != null)
			{
				grupAtacant.put(uAtacant.nom(),uAtacant);
				atacant.treureUnitat(uAtacant.nom());
			}
			while (atacant.Obtunitats().size()>1 && uAtacant != null)
			{
				uAtacant = triarUnitatMesPotent(atacant,defensor);
				grupAtacant.put(uAtacant.nom(),uAtacant);
				atacant.treureUnitat(uAtacant.nom());
			}
		}
		return grupAtacant;
	}
	
	/**
	 @pre: uAtacant i uDefensora Existeixen
	 @post: simula una Ronda de la batalla en la que s'enfronten uAtacant i uDefensores 
	 		modifica els valors  d'ambdues i retorna la unitat guanyadora.*/
	public Unitat rondaBatalla(Unitat uAtacant, Unitat uDefensora)
	{
		if (uAtacant.potencia()> uDefensora.potencia())
		{
			uAtacant.modificarQuantitat(uDefensora.potencia());
			uAtacant.modificarEspertesa();
			return uAtacant;
		}
		if (uAtacant.potencia()< uDefensora.potencia())
		{
			uDefensora.modificarQuantitat(uAtacant.potencia());
			uDefensora.modificarEspertesa();
			return uDefensora;
		}
		else
		{
			return null;
		}
	}
	/**
	 * @pre 
	 * @post simula la batalla entre atacant i defensor, atacant te les tropes grupAtacant disponibles pre 
	 * atacar defensor, retorna cert en cas de que el atacant pugui eliminar a totes les unitadts de defensor*/
	public boolean batalla(Enclavament atacant,Enclavament defensor,Map<String,Unitat> grupAtacant)
	{
		Unitat uAtacant = triarUnitatMesPotent(atacant,defensor,grupAtacant);
		Unitat uDefensora = triarUnitatMesPotent(defensor.Obtunitats());
		
		Etnia atacantb=atacant.ocupa();
		Etnia defensorab=defensor.ocupa();
		
		while (uAtacant != null && uDefensora != null)
		{
			Unitat guanyadora = rondaBatalla(uAtacant,uDefensora);
			if (guanyadora == uAtacant)
			{
				defensor.treureUnitat(uDefensora.nom());
				if (uAtacant.esNecessariCanviFormacio())
				{
					if (uAtacant.quantitat()< 10)
					{
						String nouNom ;
						atacantb.IncrementarNEsquadrons();
						Esquadro unitatNovaFormacio = new Esquadro("Esquadro"+atacantb.nom()+atacantb.ObtnEsquadrons(),uAtacant.grauEspertesa(),uAtacant.quantitat());
						grupAtacant.remove(uAtacant.nom());
						uAtacant = unitatNovaFormacio;
						grupAtacant.put(uAtacant.nom(),uAtacant);
					}
					else if (uAtacant.quantitat()<200)
					{
						atacantb.IncrementarNCompanyies();
						Companyia unitatNovaFormacio = new Companyia ("Companyia"+atacantb.nom()+atacantb.ObtnCompanyies(),uAtacant.grauEspertesa(),uAtacant.quantitat());//Hem de obtenir el nou nom
						grupAtacant.remove(uAtacant.nom());
						uAtacant = unitatNovaFormacio;
						grupAtacant.put(uAtacant.nom(),uAtacant);
					}
				}
			}
			else if (guanyadora == uDefensora)
			{
				grupAtacant.remove(uAtacant.nom());
				if (uDefensora.esNecessariCanviFormacio())
				{
					if (uDefensora.quantitat()< 10)
					{
						defensorab.IncrementarNEsquadrons();
						Esquadro unitatNovaFormacio = new Esquadro("Esquadro"+defensorab.nom()+defensorab.ObtnEsquadrons(),uDefensora.grauEspertesa(),uDefensora.quantitat());//NECESSITA NOU NOM
						defensor.treureUnitat(uDefensora.nom());
						uDefensora = unitatNovaFormacio;
						defensor.AfegirUnitats(uDefensora);
					}
					else if (uDefensora.quantitat()<200)
					{
						defensorab.IncrementarNCompanyies();
						Companyia unitatNovaFormacio = new Companyia ("Companyia"+defensorab.nom()+defensorab.ObtnCompanyies(),uDefensora.grauEspertesa(),uDefensora.quantitat());//Hem de obtenir el nou nom
						defensor.treureUnitat(uDefensora.nom());
						uDefensora = unitatNovaFormacio;
						defensor.AfegirUnitats(uDefensora);
					}
				}
			}
			else
			{
				grupAtacant.remove(uAtacant.nom());
				defensor.Obtunitats().remove(uDefensora.nom());	
			}
            uAtacant = triarUnitatMesPotent(grupAtacant);
			uDefensora = triarUnitatMesPotent(defensor.Obtunitats());
		}
		return (uAtacant != null );//queden unitats atacants (i no defensores)
	}
	
	/**
	 * @pre 
	 * @post: mira si en el enclavament llocFinal es necessari un exili de civils i si es necessari l'executa*/
	public void esNecessariExili(Enclavament llocFinal,Etnia eAtacant)
	{
		if (llocFinal.necesitaExili())
 	   	{
 		   List<String>etcivils = ((Municipi) llocFinal).obtCivils();
 		   Iterator itcivils = etcivils.iterator();
 		   while(itcivils.hasNext())
 		   {
 			   
 			   Etnia etAux = new Etnia((String)itcivils.next());
 			   etAux =(buscarEtnia(etAux.nom()));
 			   if(etAux !=eAtacant)
 			   {
 				   System.out.println(etAux.nom()+" Necesita exili:");
 				   map.Exili(llocFinal,etAux);
 				  
 			   }
 		   }
 	   	}
	}
	/**
	 * @pre: 
	 * @post: du a terme comandaAtacar,  atac de un enclavament a un altre
	 * en cas de guanyar la batalla ocupa el enclavament i mou les tropes a l'enclavament que 
	 * acaba de ocupar a mes exilia a totes les etnies(si hi ha ) que son diferents a la 
	 * etnia que acaba de ocupar el enclavament en cas de perdre la batalla, 
	 * les tropes desapareixen, en cas de enpat el enclavament queda desmilitaritzat. 
	 * Excepcions: en cas de no haver unitats militar en el enclavament final llansa una excepcio
	 * del tipus noPresenciaMilitarException. En cas de que la etnia el lloc final o el de inici no existeixen
	 * llansa una exepcio del tipus NoElementTrobatException*/
	public void atacar(Atac comandaAtacar) throws NoPresenciaMilitarException, NoElementTrobatException,OcupantException
	{
			Etnia eAtacant = comandaAtacar.etnia();
			Enclavament llocInici = comandaAtacar.enclavamentInicial();
			Enclavament llocFinal = comandaAtacar.enclavamentFinal();
			if (eAtacant != null && llocInici != null && llocFinal != null)
			{
				if (llocInici.ocupa() != null && llocInici.ocupa().equals(eAtacant))
				{
					if(llocFinal.ocupatMilitartment())
					{
						if (!llocFinal.ocupa().equals(llocInici.ocupa()))
						{
							boolean guanya;
							Map<String,Unitat> grupAtacant = unitatsPerAtacar(llocInici,llocFinal,eAtacant.estrategia());
							guanya = batalla(llocInici,llocFinal,grupAtacant);
							if (guanya)
							{
								llocFinal.ocuparMilitartment(eAtacant);
								Iterator iterator = grupAtacant.entrySet().iterator();
								while(iterator.hasNext())
								{
									Map.Entry<String,Unitat> mapEntry = (Map.Entry) iterator.next();
									llocFinal.AfegirUnitats(mapEntry.getValue());
								}
								System.out.println("la Etnia "+eAtacant.nom()+" ha guanyat la batalla");
								System.out.println("la Etnia "+eAtacant.nom()+" ha ocupat "+llocFinal.obtNom());
								esNecessariExili(llocFinal,eAtacant);
                        	   
							}
                          	else
                          	{
                          		System.err.println(eAtacant.nom()+" No ha pogut guanyar la batalla.");
                        	   	if (llocFinal.Obtunitats().isEmpty())
                                {
                        	   		llocFinal.ocuparMilitartment(null);
                        	   		System.out.println(llocFinal.obtNom()+" ha quedat desmilitaritzat");
                        	   		
                                }
                          	}
						}
						else
						{
							System.err.println("Enclavament inicial i final de la mateixa etnia");
						}
					}
					else
					{	
						//System.err.print("No es pot atacar a un enclavament sense ocupacio militar");
						throw new NoPresenciaMilitarException();
					}
				}	
				else
				{
					throw new OcupantException();
				}
			}
			else 
			{
				throw new NoElementTrobatException();
			}
	}
	
	
	
	/**
	 @pre:
	 @post: retorna la etnia amb el mateix nom a inEtnia en cas de no existir llen�a una Excepcio.*/
	public Etnia buscarEtnia(String inEtnia)
	{
			Etnia aux = etnies.get(inEtnia);
			return aux;
			
	}
	
	
	/**
	 * @pre
	 * @post du a terme una colonitzacio, en cas de poder dur a terme la colonitzacio (cap de les excepcions es cridada)
	 * afegeix a pobFinal els civils.
	 * Excepcions: en cas que Municipi inicial i final no estiguin connectats directament per una carretera llansa una excepcio
	 * del tipus CivilsNoPodenArribarException. En cas de que no hi haguin civils al llocInicial llansa excepcio del tipus
	 * NoCivilsException, En cas de que llocFinal estigui ocupat per algu llansa excepcio del tipus PresenciaMilitarExeption.
	 * En cas de que ja hi haguin civils del etnia en questio llensa excepcio del tpus PresenciaCivilException. En cas de que 
	 * etnia PobInicial o PobFinal no existeix llansa excepcio del tipus NoElementTrobatException*/
	public void colonitzar(Colonitzar colonitzar)throws CivilsNoPodenArribarException,NoCivilsException,
    PresenciaMilitarException,PresenciaCivilException,NoElementTrobatException,OcupantException
    {
		Etnia colonitzadora = colonitzar.etnia();
		Municipi PobInicial = (Municipi) colonitzar.poblacioInicial();
		Municipi PobFinal  = (Municipi) colonitzar.poblacioFinal();

		if (colonitzadora != null && PobInicial != null && PobFinal != null )
		{
			if (PobInicial.ocupa() != null && PobInicial.ocupa().equals(colonitzadora))
			{
				if (!PobFinal.hiHaCivilsEtnia(colonitzadora.nom()))
				{
					if(!PobFinal.ocupatMilitartment())
					{
						if (PobInicial.hiHaCivilsEtnia(colonitzadora.nom()))
						{
							if (PobInicial.Obtcarreteres().contains(PobFinal.obtNom()))
							{
								PobFinal.afegirCivils(colonitzadora.nom());
								System.out.println(colonitzadora.nom()+" ha afegit civils a "+PobFinal.obtNom());
							}
							else
							{	
							//System.err.print("Els civils no podem arribar a la poblacio final.");
							throw new CivilsNoPodenArribarException(); 
							}
						}
						else
						{
							//System.err.print("No hi ha civils per colonitzar ");
							throw new NoCivilsException();
						}
					}
					else
					{
						if (PobFinal.ocupa().equals(PobInicial.ocupa()))
						{
							PobFinal.afegirCivils(colonitzadora.nom());
							System.out.println(colonitzadora.nom()+" ha afegit civils a "+PobFinal.obtNom());
						}
						else
						{
							//System.err.print("poblacio ocupada militarment per un altra etnia");
							throw new PresenciaMilitarException(); 
						}
					}
				}		
				else
				{
					//System.err.print("Ja hi han civils de la etnia en questio");
					throw new PresenciaCivilException();
				}
			}
			else
			{
				throw new OcupantException();
			}
		}
		else
		{
			//System.err.print("etnia, PobFinal o PobInicial inexistent");
			throw new NoElementTrobatException();
		}
    }

/**
* @pre
* @post du a terme una Maniobra en cas de que no es llenci cap de les excepcions mou les unitats desitjades de 
* llocInicial a llocFinal.
* Exepcions: en cas de no haver unitats en llocInicial per poder moure a llocFinal llansa excepcio del tipus
* NoUnitatsExcepcion, en cas de que hi hagui unitats de etniaManiobra llansa excepcio del tipus NoPresenciaMilitarException.
* En cas de que no hi existeixi etniaManiobra llocInicial o llocFinal llansa excepcio del tipus NoElementTrobatException. */
	public void Maniobra (Maniobra maniobra) throws NoUnitatsException, NoPresenciaMilitarException, NoElementTrobatException,OcupantException
	{
		Etnia etniaManiobra =maniobra.etnia();
		Enclavament llocInicial = maniobra.llocInicial();
		Enclavament llocFinal = maniobra.llocFinal();
		if (etniaManiobra != null && llocInicial != null && llocFinal != null)
		{
			if( llocInicial.ocupa() != null && llocInicial.ocupa().equals(etniaManiobra))
			{
				Map<String,Unitat> grupEnManiobra = new TreeMap();
				if (llocFinal.ocupatMilitartment() && llocFinal.ocupa().equals(etniaManiobra))
				{
					Unitat unitatManiobra;
					int i = 0 ;
					while (i < maniobra.numeroUnitats() && llocInicial.Obtunitats().size()>1)
					{
						unitatManiobra = triarUnitatMenysPotent(llocInicial.Obtunitats());
						if (unitatManiobra != null)
						{
							llocInicial.treureUnitat(unitatManiobra.nom());
							grupEnManiobra.put(unitatManiobra.nom(),unitatManiobra);
							i++;
						}
					}

					if (!grupEnManiobra.isEmpty())
					{
						Iterator iterator = grupEnManiobra.entrySet().iterator();
						while(iterator.hasNext())
						{
							Map.Entry<String,Unitat> mapEntry = (Map.Entry) iterator.next();
							llocFinal.Obtunitats().put(mapEntry.getKey(),mapEntry.getValue());		
						}
						System.out.println("les unitats han estat movudes corrrectament.");
						System.out.println("de: "+llocInicial.obtNom()+" a "+llocFinal.obtNom());
					}
					else
					{
						//System.err.print("No hi ha unitats per moure al enclavament inicial");
						throw new NoUnitatsException();
					}
				}
				else
				{
					//System.err.print("No hi ha militars de l'etnia al enclavament final");
					throw new NoPresenciaMilitarException();
				}
			}
			else
			{
				throw new OcupantException();
			}
		}
		else
		{
			//System.err.print("etnia, llocInicial o llocFinal inexistent");
			throw new NoElementTrobatException();
		}

	}

/**
* @pre:
* @post: du a terme un canvi de estrategia, en cas de que no llenci una excepcio.
* Excepcio: en cas de que la etnia no exiteixi llansa excepcio del tipus EtniaException*/
	public void canviEstrategia(Etnia etnia) throws EtniaException
	{
		
		if (etnia != null)
		{
			etnia.canviEstrategia();
			System.out.println("l'etnia: "+etnia.nom()+" ha canviat d'estrategia a: "+etnia.estrategia());
		}
		else
		{
			throw new EtniaException();
		}

	}

/**
* @pre 
* @post du a terme una ocupacio en cas de que cap de les excepcions sigui llansada mou les x unitats de 
* llocInici a llocFinal
* Excepcions: en cas de que el enclavament inicial no pugui moure cap unitat llensa una excepcio del tipus
* NoUnitatsException. En cas de que hi hagui presencia militar de qualsevol etnia llensa excepcio del tipus
* PresenciaMilitarException. */
	public void ocupacio (Ocupacio ocupacio) throws NoUnitatsException, PresenciaMilitarException,NoElementTrobatException,OcupantException
	{
		Etnia etniaOcupa = ocupacio.etnia();
		Enclavament llocInici = ocupacio.enclavamentInicial();
		Enclavament llocFinal = ocupacio.enclavamentFinal();

		if (etniaOcupa != null && llocInici !=null && llocFinal != null)
		{
			if(llocInici.ocupa() != null && llocInici.ocupa().equals(etniaOcupa))
			{
				if (!llocFinal.ocupatMilitartment())
				{
					Map<String,Unitat> grupOcupa;
					grupOcupa = unitatsPerOcupar(llocInici,llocFinal,ocupacio.unitats(),etniaOcupa.estrategia());
		
					if (grupOcupa.size()>0)
					{
						Iterator iterator = grupOcupa.entrySet().iterator();
						while(iterator.hasNext())
						{
							Map.Entry<String,Unitat> mapEntry = (Map.Entry) iterator.next();
							llocFinal.Obtunitats().put(mapEntry.getKey(),mapEntry.getValue());
						}
						llocFinal.ocuparMilitartment(etniaOcupa);
						System.out.println(etniaOcupa.nom() +" ha ocupat "+llocFinal.obtNom()+ " desde "+llocInici.obtNom());
						esNecessariExili(llocFinal,etniaOcupa);
					}
					else
					{
						//System.print.err("El enclavament inicial no pot moure tropes.")
						throw new NoUnitatsException();
					}
					
				}
				else
				{
					//System.print.err("El enclavament final es ocupat militarment per algu.")
					throw new PresenciaMilitarException();
				}
			}
			else
			{
				throw new OcupantException();
			}
		}
		else
		{
			throw new NoElementTrobatException();
		}

}

/**
* @pre
* @post retorna un map amb les unitats que es puguin moure desde eInicial a eFinal en cas de que el mode
* sigui conservador les envia de menys potent a mes, en cas de agresiu envia de mes potennt a menys, el numero 
* de unitats que es mouen son int unitats, en cas de no poder moure tantes unitats mou les disponibles 
* es posible retornar el map buit.*/
public Map<String,Unitat> unitatsPerOcupar(Enclavament eInicial, Enclavament eFinal,int unitats,String mode)
{
Unitat uOcupa = null;
int i = 0 ;
Map<String,Unitat> unitatsQueOcupen = new TreeMap();

if (mode.equals("conservador"))
{	
uOcupa= triarUnitatMenysPotent(eInicial,eFinal);
while (eInicial.Obtunitats().size()>1 && uOcupa != null && i < unitats)
{
	eInicial.treureUnitat(uOcupa.nom());
	unitatsQueOcupen.put(uOcupa.nom(),uOcupa);
	uOcupa = triarUnitatMenysPotent(eInicial,eFinal);
}

}
else //agressiu
{
uOcupa= triarUnitatMesPotent(eInicial,eFinal,eInicial.Obtunitats());
while (eInicial.Obtunitats().size()>1 && uOcupa != null && i < unitats)
{
	eInicial.treureUnitat(uOcupa.nom());
	unitatsQueOcupen.put(uOcupa.nom(),uOcupa);
	uOcupa = triarUnitatMesPotent(eInicial,eFinal,eInicial.Obtunitats());
} 
}
return unitatsQueOcupen;
}
}